通俗理解: 通过与自身有关联的表数据,查询自身表数据

跨多张表查询自身的数据的前提是,这多张表必须有关联

通过 .filter(xxx__xxx='xxx') 实现

1.表的结构

# models.py

from django.db import models


# 书
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
    publish_date = models.DateField(auto_now_add=True, verbose_name='出版日期')
    price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格')
    memo = models.TextField(null=True, verbose_name='说明')
# 创建外键,关联publish
    publisher = models.ForeignKey(to='Publisher', verbose_name='出版社')
# 创建多对多关联author
    author = models.ManyToManyField(to='Author', verbose_name='作者')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = "书籍"
        verbose_name_plural = verbose_name


# 出版社
class Publisher(models.Model):
    name = models.CharField(max_length=32, verbose_name='出版社名称')
    city = models.CharField(max_length=32, verbose_name='地址')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "出版社"
        verbose_name_plural = verbose_name


# 作者
class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    phone = models.CharField(max_length=11, verbose_name='手机号码')
 # 创建一对一关联authorDetail
    detail = models.OneToOneField(to='AuthorDetail', verbose_name='详情')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "作者"
        verbose_name_plural = verbose_name


# 作者详情
class AuthorDetail(models.Model):
    addr = models.CharField(max_length=64, verbose_name='地址')
    email = models.EmailField(verbose_name='邮箱')

    def __str__(self):
        return self.addr

    class Meta:
        verbose_name = "作者详情"
        verbose_name_plural = verbose_name

2.正向查询

  • 语法: .filter(主表类的外键属性名__从表字段名='xxx', ……)

    • 查询出书籍的 作者是yeung 的数据

book_list = Book.objects.filter(author__name='yeung')

    • 查询出书籍的 作者是yeung,出版社是东莞出版社 的数据

book_list = Book.objects.filter(author__name='yeung').filter(publisher__name='东莞出版社')

# 等同于

book_list = Book.objects.filter(author__name='yeung', publisher__name='东莞出版社')

3. 反向查询

  • 语法:

    • 如果没有设置表类中外键属性的 related_name

      • .filter(主表类名__主表字段名='xxx', ……)

# 查询出书名为西游记的作者

author = Author.objects.filter(book__title='西游记')

    • 如果设置了表类中外键属性的 related_name

      • .filter(related_name所设置的名字__主表字段名='xxx', ……)

# models.py

class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
    publish_date = models.DateField(auto_now_add=True, verbose_name='出版日期')
    price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格')
    memo = models.TextField(null=True, verbose_name='说明')
 # 创建外键,关联publish
    publisher = models.ForeignKey(to='Publisher', verbose_name='出版社')
# 创建多对多关联author
    author = models.ManyToManyField(to='Author', verbose_name='作者', related_name='mf_book')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = "书籍"
        verbose_name_plural = verbose_name

# 查询出书名为西游记的作者

author = Author.objects.filter(mf_book__title='西游记')